#include "Text.h"
#include <sstream>

Text::Text(std::string text)
{
	/**
	Constructor can set text when initializing the members

	tstring text sets the default text to appear on screen
	default pointsize is 100.
	*/

	this->text = text;
	pointSize = 100;
	X = Y = 0.0f;
	r = g = b = a = 1.0f;
	Animate = false;
	textAnimation.SetFPSRate(5);
}

Text::~Text()
{
	/**
	delete data when not used anymore
	*/
	pFont->Release();
	delete texture;
}

void Text::update()
{
	/**
	updates the text when changed (private function member)
	*/
	pFont->Release();

	HRESULT hr;
	hr = D3DXCreateFont( d3ddev, 
						 pointSize, 
						 pointSize/2, 
						 0,
						 0, 
						 FALSE, 
		                 DEFAULT_CHARSET, 
						 OUT_DEFAULT_PRECIS, 
						 DEFAULT_QUALITY, 
		                 DEFAULT_PITCH | FF_DONTCARE, 
						 TEXT("Arial"), 
		                 &pFont );

	if( FAILED(hr) )
		_cprintf("Failed to create font!\n");

	SetRect( &rect, (int)X, 50+(int)Y, 50+(int)X, (int)Y );
}

std::string Text::convertDouble(double value)
{
	/**
	Converts a number into a string
	*/

	std::ostringstream o;
	if (!(o << value))
	  return "";
	return o.str();
}

void Text::init(LPDIRECT3DDEVICE9 d3ddev)
{
	/**
	Initialize the class with a ptr to the diret3d device needed for rendering.
	Have directx allocate the memory to create the font data.
	
	Writes to console if it fails.
	*/
	HRESULT hr;
	hr = D3DXCreateFont( d3ddev, 
						 pointSize, 
						 pointSize/2, 
						 0, 
						 0, 
						 FALSE, 
		                 DEFAULT_CHARSET, 
						 OUT_DEFAULT_PRECIS, 
						 DEFAULT_QUALITY, 
		                 DEFAULT_PITCH | FF_DONTCARE, 
						 TEXT("Arial"), 
		                 &pFont );

	if( FAILED(hr) )
		_cprintf("Failed to create font!\n");

	this->d3ddev = d3ddev;

	SetRect( &rect, (int)X, 50+(int)Y, 50+(int)X, (int)Y );

	texture = new Texture(d3ddev);
	if(!texture->LoadTexture("../../Art/white.png"))
		_cprintf("failed to load texture -> Text!\n");

}

void Text::FpsRate(int rate)
{
	/**
	Set Animation Speed
	*/

	textAnimation.SetFPSRate(rate);
}

void Text::updateAnimation(float dt)
{
	/**
	Update Text Animation
	*/

	textAnimation.Start(dt);
}

void Text::SetColor(float r, float g, float b)
{
	/**
	Set Text Color
	*/

	this->r = r;
	this->g = g;
	this->b = b;
}

void Text::SetColor(float r, float g, float b, float a)
{
	/**
	Set Text Color And Alpha
	*/

	this->r = r;
	this->g = g;
	this->b = b;
	this->a = a;
}

void Text::setPointSize(int size)
{
	/**
	Set the pointsize of the text

	takes an integer pointSize
	*/
	pointSize = size;
	this->update();
}

void Text::setText(std::string text)
{
	/**
	Set the string to display
	*/

	this->text = text;
	textAnimation.SetEndFrame(this->text.length());
}

void Text::setText(double number)
{
	/**
	Set the string to display
	*/

	this->text = this->convertDouble(number);
	textAnimation.SetEndFrame(this->text.length());
}

void Text::setText(int number)
{
	/**
	Set the string to display
	*/

	char _t[5];
	_itoa_s(number, _t, 10);

	this->text = _t;
	textAnimation.SetEndFrame(this->text.length());
}

void Text::addText(std::string text)
{
	/**
	Set the string to display
	*/

	this->text.append(text);
	textAnimation.SetEndFrame(this->text.length());
}

void Text::addText(double number)
{
	/**
	Set the string to display
	*/

	this->text.append(convertDouble(number));
	textAnimation.SetEndFrame(this->text.length());
}

void Text::addText(int number)
{
	/**
	Set the string to display
	*/

	char _t[5];
	_itoa_s(number, _t, 10);

	this->text.append(_t);
	textAnimation.SetEndFrame(this->text.length());
}

void Text::setPosition(float x, float y)
{
	/**
	Set Text Position
	*/

	X = x;
	Y = y;

	update();
}

void Text::setPosition(Entity * object)
{
	/**
	Set text position according to object. (Not working at the moment)
	*/
	if( d3ddev != NULL )
	{
		D3DXVECTOR3 ScreenPos;
		ZeroMemory(&ScreenPos, sizeof( D3DXVECTOR3 ) );
		D3DXMATRIXA16 inWorldMat;
		D3DXMatrixTranslation(&inWorldMat, object->GetXPosition(), object->GetYPosition(), object->GetZPosition() );
		inWorldMat *= cameraMatrix;
		D3DXMATRIXA16 inProjMat;
		D3DXMATRIXA16 inViewMat;
		d3ddev->GetTransform( D3DTS_PROJECTION, &inProjMat);
		d3ddev->GetTransform( D3DTS_VIEW, &inViewMat);
		
		D3DXVECTOR3 Temp;
		ZeroMemory(&Temp, sizeof( D3DXVECTOR3 ) );
		D3DVIEWPORT9 viewPort;
		d3ddev->GetViewport(&viewPort);
		D3DXVec3Project(&ScreenPos, &Temp, &viewPort, &inProjMat, &inViewMat, &inWorldMat);

		X = ScreenPos.x;
		Y = ScreenPos.y;
	}
	else
		_cprintf("Text : %s -> setPosition(Entity * object) Failed!\n", text);
}

void Text::UseAnimation(bool b)
{
	/**
	Turn On/Off Text Animation
	*/
	this->Animate = b;
}

void Text::Render(LPDIRECT3DDEVICE9 d3ddev)
{
	/**
	Render the string onto the screen.
	*/

	

	if(!Animate)
		pFont->DrawText( 0, text.c_str() , -1, &rect, DT_LEFT|DT_VCENTER|DT_NOCLIP, 
							   D3DXCOLOR(r, g, b, a) );
	else
	{
		std::string sub;
		sub = text.substr(0, textAnimation.GetCurrentFrame());
		
		pFont->DrawText( 0, sub.c_str() , -1, &rect, DT_LEFT|DT_VCENTER|DT_NOCLIP, 
							   D3DXCOLOR(r, g, b, a) );
	}
}